#include <array>
#include <filesystem> // For std::filesystem::current_path
#include <fstream>
#include <iostream>
#include <string>
#include <unordered_map>
#include <vector>

#include "get_output_filename.h"
#include "global_var.h"
#include "handle_line.h"
#include "parse_config.h"
#include "select_line.h"
#include "sort_csv_by_time.h"

#include "widget.h"

#include <QApplication>

//using namespace std;

/**
 * 1. 新增debug模式
 * 	1.1 -h 参数，--help
 * 	1.2 -d 参数，--debug
 * 	1.3 当前只可一次加一个参数，想要一次多个参数需要getopt.h之类的命令行解析库
 * 2. 新增配置文件：配置文件中有需要读取的传感器名称
 * 	2.1 配置文件名称`ntc_config.conf`
 * 3. 可以自定义函数，根据不同的日志格式自己定义抓相应数据的函数（与配置文件强相关）
 *
 * 4. 优化
 * 	4.1 解析一行输入一行，防止解析结果过大占用太多空间
 * 	4.2 一行中查找各数字字段时，只用一组头&尾标记：cur_focus_beg, cur_focus_end
 * 	4.3 专门写一个查找当前位置向后首个数字的函数，足够robust
 * 		4.3.1 `if ('0'<=ch && ch<='9')`
 * 	4.4 全局变量vector保存配置字段 https://lxblog.com/qianwen/share?shareId=c2b71046-e394-44e9-888a-3930ab4ee9f2
 * 5. 新增
 * 	√5.1 输出文件名末尾增加时间戳
 * 	√5.2 不同机型设置不同的配置文件，目前已有机型：o11u, n12a
 * 	√5.3 场景名称
 * 	√5.4 功能：默认解析当前目录下名为dumpstate_board.txt文件
 * 	√5.5 thermal侧CPU频率天花板
 * 	5.6 输出文件按时间排序
 * 	√5.7 绘制折线图
 */

// 头文件重复定义报错：https://lxblog.com/qianwen/share?shareId=bdf21966-c662-44cb-868d-5f188d56cd16
/**
 * todo:
 * 1. 扩展ntcs：添加更多功能，将成员变为结构体变量，结构体包含以下成员变量：is_temp, is_default, need_draw
 * 2. .csv文件按时间排序
 * 3. 滚动放大横坐标轴
 * 4. 点击曲线上的点显示该点坐标
 * 5. 保存折线图
 */
int debug_mod=0;
int time_column;
std::string output_csv_filename;
std::string sorted_csv_filename;
std::vector<std::string> ntcs;

void show_help();

int main(int argc, char *argv[])
{
    // check parameter
    // 可以用map实现类似switch的功能，来实现处理当前接收到的各种参数
    // https://lxblog.com/qianwen/share?shareId=ec0a80ce-f1e9-4882-9866-e0d44015c94a
    std::string device_name="";
    for(int i=1;i<argc;++i){
        std::string arg=argv[i];
        if(arg=="--help"||arg=="-h"){
            show_help();
            return 0;
        }
        else if(arg=="--debug"||arg=="-debug"){
            debug_mod=1;
        }
        else if(arg=="--device" || arg=="-d"){
            if((i+1)<argc){
                device_name=argv[i+1];
            }
        }
    }
    // 程序逻辑部分
    // 1. 输出文件表头
    parse_config(ntcs, device_name);
    output_csv_filename="";
    output_csv_filename=get_output_filename();
    std::ofstream file_target(output_csv_filename);
    std::string log_path="";//debug
    std::cout<<"pls input dumpstate_board.txt file path: "<<std::endl;
    std::cout.flush(); // 强制刷新输出缓冲区
    getline(std::cin, log_path);
    // 默认解析：当前目录下dumpstate_board.txt
    if(log_path==""){
        log_path="./dumpstate_board.txt";
        std::cout<<"parse default file \"./dumpstate_board.txt\""<<std::endl;
    }
    std::ifstream file_log(log_path);
    if(file_target.is_open() && file_log.is_open()){
        file_target<<ntcs[0];
        for(int i=1; i<ntcs.size(); i++){
            file_target<<","<<ntcs[i];
        }
        file_target<<std::endl;
        // 2. 逐行处理日志文件
        std::string line_cur;
        while(getline(file_log, line_cur)){
            // 找到关键字则处理，没找到啥都不做
            // todo: 此处要将固定的几个属性加入默认通用配置
            std::string key_word;
            for(int i=0; i<ntcs.size(); i++){
                if(ntcs[i]!="time" && ntcs[i]!="scenario"){
                    key_word=ntcs[i];
                    break;
                }
            }
            if(select_line(line_cur, key_word)!=string::npos){
                /**
                 * 此处有少许优化空间
                 * 需将ntcs顺序修改为log行中出现的顺序
                 * 然后每次向后找，避免每次从头查找字段
                 */
                handle_line(line_cur, ntcs, file_target);
            }
        }
        // 3. todo逐行处理完毕，按时间排序

    }
    else if(!file_log.is_open()){
        std::cout<<"\033[031m"<<"Error opening file."<<"\033[0m"<<std::endl;
    }
    else if(!file_target.is_open()){
        std::cout<<"\033[031m"<<"Error creating file."<<"\033[0m"<<std::endl;
    }
    /* 对初版.csv按时间列排序 */
    sort_csv_by_time();

    QApplication a(argc, argv);
    /* initialize Widget var w */
    Widget w;
    w.show();
    return a.exec();
}

void show_help(){
    std::cout<<"usage: parse [-h|--help] [-debug|--debug] [-d|--device <device name>]"<<std::endl;
}
